home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / varia / grammar1.lha / c++grammar1.1 / cpp4.l < prev    next >
Text File  |  1990-06-07  |  16KB  |  370 lines

  1. %{
  2.     /* Copyright (C) 1989,1990 James A. Roskind, All rights reserved. 
  3.     This lexer description was written by James A.  Roskind.  Copying 
  4.     of  this  file, as a whole, is permitted providing this notice is 
  5.     intact  and  applicable   in   all   complete   copies.    Direct 
  6.     translations  as a whole to other lexer generator input languages 
  7.     (or lexical description languages)  is  permitted  provided  that 
  8.     this  notice  is  intact and applicable in all such copies, along 
  9.     with a disclaimer that  the  contents  are  a  translation.   The 
  10.     reproduction  of derived files or text, such as modified versions 
  11.     of this file, or the output of scanner generators, is  permitted, 
  12.     provided   the  resulting  work  includes  the  copyright  notice 
  13.     "Portions Copyright (c) 1989, 1990 James  A.   Roskind".  Derived 
  14.     products  must  also  provide  the notice "Portions Copyright (c) 
  15.     1989, 1990 James A.  Roskind" in  a  manner  appropriate  to  the 
  16.     utility,   and  in  keeping  with  copyright  law  (e.g.:  EITHER 
  17.     displayed when first invoked/executed; OR displayed  continuously 
  18.     on  display terminal; OR via placement in the object code in form 
  19.     readable in a printout, with or near the title of the work, or at 
  20.     the end of the file).  No royalties, licenses or  commissions  of 
  21.     any  kind  are  required  to copy this file, its translations, or 
  22.     derivative products, when the copies are made in compliance  with 
  23.     this  notice.  Persons  or  corporations  that  do make copies in 
  24.     compliance  with  this  notice  may  charge  whatever  price   is 
  25.     agreeable  to  a buyer, for such copies or derivative works. THIS 
  26.     FILE IS PROVIDED ``AS IS'' AND WITHOUT  ANY  EXPRESS  OR  IMPLIED 
  27.     WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES 
  28.     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  29.  
  30.     James A. Roskind
  31.     Independent Consultant
  32.     516 Latania Palm Drive
  33.     Indialantic FL, 32903
  34.     (407)729-4348
  35.     jar@ileaf.com
  36.     or ...!uunet!leafusa!jar
  37.  
  38.     ---end of copyright notice---
  39.  
  40.  
  41. COMMENTS-
  42.  
  43. My  goal  is  to  see  software  developers adopt my C++ grammar as a 
  44. standard until such time as a better  standard  is  accessible.   The 
  45. only  way  to  get it to become a standard, is to be sure that people 
  46. know that derivations are based on a specific work.   The  intent  of 
  47. releasing  this Flex input file is to facilitate experimentation with 
  48. my C++ grammar. The intent  of  the  copyright  notice  is  to  allow 
  49. arbitrary  commercial and non-commercial use of this file, as long as 
  50. reference is given to my standardization effort.   Without  reference 
  51. to  a specific standard, many alternative grammars would develop.  By 
  52. referring to the standard, the C++ grammar is given publicity,  which 
  53. should  lead  to further use in compatible products and systems.  The 
  54. benefits  of  such  a  standard  to  commercial  products  (browsers, 
  55. beautifiers,  translators,  compilers,  ...) should be obvious to the 
  56. developers, in that other compatible products will  emerge,  and  the 
  57. value  of  all  conforming  products  will rise.  Most developers are 
  58. aware of the value of acquiring  a  fairly  complete  grammar  for  a 
  59. language,  and  the  copyright  notice (and the resulting affiliation 
  60. with my work) should not be too high a price to pay.  By copyrighting 
  61. my work, I have some minor control over what this standard is, and  I 
  62. can  (hopefully)  keep it from degrading without my approval.  I will 
  63. consistently attempt to provide upgraded grammars that are  compliant 
  64. with  the  current  art, and the ANSI C++ Committee recommendation in 
  65. particular.  A  developer  is  never  prevented  from  modifying  the 
  66. grammar or this file to improve it in whatever way is seen fit. There 
  67. is  also  no  restriction on the sale of copies, or derivative works, 
  68. providing the request in the copyright notice are satisfied.
  69.  
  70. If you are not "copying" my work, but  are  rather  only  abstracting 
  71. some of my work, an acknowledgment with references to such a standard 
  72. would  be  appreciated.  Specifically, agreements with my grammar and 
  73. its resolution of otherwise ambiguous constructs, should be noted.
  74.  
  75. Simply put: "make whatever use you would like of the grammar and this 
  76. file, but include the ``portions Copyright ...'' as  a  reference  to 
  77. this standard."
  78.  
  79.  
  80. */
  81.  
  82.  
  83. /* Last modified 3/7/90, Version 1.00 */
  84.  
  85.  
  86. /* File CPP4.L, becomes yy.lex.c after processing by FLEX  */
  87.  
  88. /* This file is a dramatically cut down version  of  the  FLEX  input 
  89. file  used in my ANSI C Preprocessor.  The executable version of my C 
  90. preprocessor is available on many platforms (shareware), but this  is 
  91. the  only source extract that is currently being distributed.  If you 
  92. need  a  full  ANSI  C  preprocessor,   with   extensive   diagnostic 
  93. capabilities  and  customization facilities, please contact me at the 
  94. addresses given above.  Current platforms  include  IBMPC  (DOS/OS2), 
  95. Sun  (SPARC  and  Motorola),  and  IBM R/6000.  ... end of commercial 
  96. announcement.
  97.  
  98. This file is being distributed to facilitate experimentation and  use 
  99. of my C and C++ grammar.
  100.  
  101.  
  102. Comment  removal  must be done during the lexing, as context (such as 
  103. enclosure in string literals) must be observed.   For  this  cut-down 
  104. lexer,  we  will assume that comments have been removed (don't assume 
  105. this if you are writing a compiler or browser!).   The  justification 
  106. for   this   assumption   is   a   view   that   we   are  processing 
  107. post-preprocessed source, and hence comment removal was taken care of 
  108. during that phase. Note that in real life, comments CANNOT always  be 
  109. removed  prior  to  lexing,  as  the  sequence of characters '/*' may 
  110. appear within a string literal, and hence NOT indicate the start of a 
  111. comment.
  112.  
  113. For each IDENTIFIER like string that  is  found,  there  are  several 
  114. distinct interpretations that can be applied:
  115.  
  116. 1)  The  preprocessor  may  interpret  the string as a "keyword" in a 
  117. directive (eg: "pragma" or "include", "defined").
  118.  
  119. 2) The parser may interpret the string as a keyword. (eg: "int").
  120.  
  121. 3) Both parser and preprocessor may interpret the string as a keyword 
  122. (eg: "if").
  123.  
  124. Since this file is based on source that actually  lexically  analyses 
  125. text  for both preprocessing and parsing, macro definitions were used 
  126. throughout.  The macro definitions supplied here have been customized 
  127. to a C++ parse only, and all  preprocessor  keywords  are  passed  as 
  128. IDENTIFIER  or  TYPEDEFname.  Also, since there is no symbol table to 
  129. interrogate to decide whether a string is  a  TYPEDEFname,  I  simply 
  130. assume  that  any identifier beginning with an upper case letter is a 
  131. TYPEDEFname.  This hack should  allow  you  to  check  out  how  code 
  132. segments  are  parsed using my grammar.  Unfortunately, if you really 
  133. want to parse major league code, you have to write  a  symbol  table, 
  134. and maintain appropriate scoping information.  :-), sorry...
  135.  
  136. */
  137.  
  138.  
  139. /* Included code before lex code */
  140. /*************** Includes and Defines *****************************/
  141.  
  142.  
  143. #include "y.tab.h" /* YACC generated definitions based on C++ parser input*/
  144.  
  145. typedef char * YYSTYPE; /* interface with lexer: should be in header file*/
  146.  
  147. char * yylval; /* We will always point at the text of the lexeme.
  148.     This  makes  it  easy  to  print  out  nice trees when YYDEBUG is 
  149.     enabled  (see  the  C++  grammar  file,  and  its  definition  of 
  150.     YYDEBUG_LEXER_TEXT to be "yylval") */
  151.  
  152.     
  153. #define WHITE_RETURN(x)  /* do nothing,  */
  154.  
  155. #define NEW_LINE_RETURN() WHITE_RETURN('\n')
  156.  
  157. #define PA_KEYWORD_RETURN(x)   RETURN_VAL(x)  /* standard C PArser Keyword */
  158. #define CPP_KEYWORD_RETURN(x)  PA_KEYWORD_RETURN(x)  /* C++ keyword */
  159. #define PPPA_KEYWORD_RETURN(x) RETURN_VAL(x)  /* both PreProcessor and PArser keyword */
  160. #define PP_KEYWORD_RETURN(x)   IDENTIFIER_RETURN()
  161.  
  162. #define IDENTIFIER_RETURN() RETURN_VAL(isaTYPE(yytext)?TYPEDEFname:IDENTIFIER) 
  163.  
  164. #define PPOP_RETURN(x)       RETURN_VAL((int)*yytext) /* PreProcess and Parser operator */
  165. #define NAMED_PPOP_RETURN(x) /* error: PreProcessor ONLY operator;  Do nothing */
  166. #define ASCIIOP_RETURN(x)    RETURN_VAL((int)*yytext) /* a single character operator */
  167. #define NAMEDOP_RETURN(x)    RETURN_VAL(x)            /* a multichar operator, with a name */
  168.  
  169. #define NUMERICAL_RETURN(x) RETURN_VAL(x)            /* some sort of constant */
  170. #define LITERAL_RETURN(x)   RETURN_VAL(x)            /* a string literal */
  171.  
  172. #define RETURN_VAL(x) yylval = yytext; return(x);
  173.  
  174.  
  175. %}
  176.  
  177. identifier [a-zA-Z_][0-9a-zA-Z_]*
  178.  
  179. exponent_part [eE][-+]?[0-9]+
  180. fractional_constant ([0-9]*"."[0-9]+)|([0-9]+".")
  181. floating_constant (({fractional_constant}{exponent_part}?)|([0-9]+{exponent_part}))[FfLl]?
  182.  
  183. integer_suffix_opt ([uU]?[lL]?)|([lL][uU])
  184. decimal_constant [1-9][0-9]*{integer_suffix_opt}
  185. octal_constant "0"[0-7]*{integer_suffix_opt}
  186. hex_constant "0"[xX][0-9a-fA-F]+{integer_suffix_opt}
  187.  
  188. simple_escape [abfnrtv'"?\\]
  189. octal_escape  [0-7]{1,3}
  190. hex_escape "x"[0-9a-fA-F]+
  191.  
  192. escape_sequence [\\]({simple_escape}|{octal_escape}|{hex_escape})
  193. c_char [^'\\\n]|{escape_sequence}
  194. s_char [^"\\\n]|{escape_sequence}
  195.  
  196. h_tab [\011]
  197. form_feed [\014]
  198. v_tab [\013]
  199. c_return [\015]
  200.  
  201. horizontal_white [ ]|{h_tab}
  202.  
  203. %%
  204.  
  205.  
  206. {horizontal_white}+     {
  207.                         WHITE_RETURN(' ');
  208.                         }
  209.  
  210. ({v_tab}|{c_return}|{form_feed})+   { 
  211.                         WHITE_RETURN(' ');
  212.                         }
  213.  
  214.  
  215. ({horizontal_white}|{v_tab}|{c_return}|{form_feed})*"\n"   {
  216.                         NEW_LINE_RETURN();
  217.                         }
  218.  
  219. auto                {PA_KEYWORD_RETURN(AUTO);}
  220. break               {PA_KEYWORD_RETURN(BREAK);}
  221. case                {PA_KEYWORD_RETURN(CASE);}
  222. char                {PA_KEYWORD_RETURN(CHAR);}
  223. const               {PA_KEYWORD_RETURN(CONST);}
  224. continue            {PA_KEYWORD_RETURN(CONTINUE);}
  225. default             {PA_KEYWORD_RETURN(DEFAULT);}
  226. define             {PP_KEYWORD_RETURN(DEFINE);}
  227. defined            {PP_KEYWORD_RETURN(OPDEFINED);}
  228. do                  {PA_KEYWORD_RETURN(DO);}
  229. double              {PA_KEYWORD_RETURN(DOUBLE);}
  230. elif                {PP_KEYWORD_RETURN(ELIF);}
  231. else              {PPPA_KEYWORD_RETURN(ELSE);}
  232. endif              {PP_KEYWORD_RETURN(ENDIF);}
  233. enum                {PA_KEYWORD_RETURN(ENUM);}
  234. error              {PP_KEYWORD_RETURN(ERROR);}
  235. extern              {PA_KEYWORD_RETURN(EXTERN);}
  236. float               {PA_KEYWORD_RETURN(FLOAT);}
  237. for                 {PA_KEYWORD_RETURN(FOR);}
  238. goto                {PA_KEYWORD_RETURN(GOTO);}
  239. if                {PPPA_KEYWORD_RETURN(IF);}
  240. ifdef              {PP_KEYWORD_RETURN(IFDEF);}
  241. ifndef             {PP_KEYWORD_RETURN(IFNDEF);}
  242. include            {PP_KEYWORD_RETURN(INCLUDE); }
  243. int                 {PA_KEYWORD_RETURN(INT);}
  244. line               {PP_KEYWORD_RETURN(LINE);}
  245. long                {PA_KEYWORD_RETURN(LONG);}
  246. pragma             {PP_KEYWORD_RETURN(PRAGMA);}
  247. register            {PA_KEYWORD_RETURN(REGISTER);}
  248. return              {PA_KEYWORD_RETURN(RETURN);}
  249. short               {PA_KEYWORD_RETURN(SHORT);}
  250. signed              {PA_KEYWORD_RETURN(SIGNED);}
  251. sizeof              {PA_KEYWORD_RETURN(SIZEOF);}
  252. static              {PA_KEYWORD_RETURN(STATIC);}
  253. struct              {PA_KEYWORD_RETURN(STRUCT);}
  254. switch              {PA_KEYWORD_RETURN(SWITCH);}
  255. typedef             {PA_KEYWORD_RETURN(TYPEDEF);}
  256. undef              {PP_KEYWORD_RETURN(UNDEF);}
  257. union               {PA_KEYWORD_RETURN(UNION);}
  258. unsigned            {PA_KEYWORD_RETURN(UNSIGNED);}
  259. void                {PA_KEYWORD_RETURN(VOID);}
  260. volatile            {PA_KEYWORD_RETURN(VOLATILE);}
  261. while               {PA_KEYWORD_RETURN(WHILE);}
  262.  
  263.  
  264. class               {CPP_KEYWORD_RETURN(CLASS);}
  265. delete              {CPP_KEYWORD_RETURN(DELETE);}
  266. friend              {CPP_KEYWORD_RETURN(FRIEND);}
  267. inline              {CPP_KEYWORD_RETURN(INLINE);}
  268. new                 {CPP_KEYWORD_RETURN(NEW);}
  269. operator            {CPP_KEYWORD_RETURN(OPERATOR);}
  270. overload            {CPP_KEYWORD_RETURN(OVERLOAD);}
  271. protected           {CPP_KEYWORD_RETURN(PROTECTED);}
  272. private             {CPP_KEYWORD_RETURN(PRIVATE);}
  273. public              {CPP_KEYWORD_RETURN(PUBLIC);}
  274. this                {CPP_KEYWORD_RETURN(THIS);}
  275. virtual             {CPP_KEYWORD_RETURN(VIRTUAL);}
  276.  
  277. {identifier}          {IDENTIFIER_RETURN();}
  278.  
  279. {decimal_constant}  {NUMERICAL_RETURN(INTEGERconstant);}
  280. {octal_constant}    {NUMERICAL_RETURN(OCTALconstant);}
  281. {hex_constant}      {NUMERICAL_RETURN(HEXconstant);}
  282. {floating_constant} {NUMERICAL_RETURN(FLOATINGconstant);}
  283.  
  284.  
  285. "L"?[']{c_char}+[']     {
  286.                         NUMERICAL_RETURN(CHARACTERconstant);
  287.                         }
  288.  
  289.  
  290. "L"?["]{s_char}*["]     {
  291.                         LITERAL_RETURN(STRINGliteral);}
  292.  
  293.  
  294. "("                  {PPOP_RETURN(LP);}
  295. ")"                  {PPOP_RETURN(RP);}
  296. ","                  {PPOP_RETURN(COMMA);}
  297. "#"                  {NAMED_PPOP_RETURN('#') ;} 
  298. "##"                 {NAMED_PPOP_RETURN(POUNDPOUND);}
  299.  
  300. "{"                  {ASCIIOP_RETURN(LC);}
  301. "}"                  {ASCIIOP_RETURN(RC);}
  302. "["                  {ASCIIOP_RETURN(LB);}
  303. "]"                  {ASCIIOP_RETURN(RB);}
  304. "."                  {ASCIIOP_RETURN(DOT);}
  305. "&"                  {ASCIIOP_RETURN(AND);}
  306. "*"                  {ASCIIOP_RETURN(STAR);}
  307. "+"                  {ASCIIOP_RETURN(PLUS);}
  308. "-"                  {ASCIIOP_RETURN(MINUS);}
  309. "~"                  {ASCIIOP_RETURN(NEGATE);}
  310. "!"                  {ASCIIOP_RETURN(NOT);}
  311. "/"                  {ASCIIOP_RETURN(DIV);}
  312. "%"                  {ASCIIOP_RETURN(MOD);}
  313. "<"                  {ASCIIOP_RETURN(LT);}
  314. ">"                  {ASCIIOP_RETURN(GT);}
  315. "^"                  {ASCIIOP_RETURN(XOR);}
  316. "|"                  {ASCIIOP_RETURN(PIPE);}
  317. "?"                  {ASCIIOP_RETURN(QUESTION);}
  318. ":"                  {ASCIIOP_RETURN(COLON);}
  319. ";"                  {ASCIIOP_RETURN(SEMICOLON);}
  320. "="                  {ASCIIOP_RETURN(ASSIGN);}
  321.  
  322. ".*"                 {NAMEDOP_RETURN(DOTstar);}
  323. "::"                 {NAMEDOP_RETURN(CLCL);}
  324. "->"                 {NAMEDOP_RETURN(ARROW);}
  325. "->*"                {NAMEDOP_RETURN(ARROWstar);}
  326. "++"                 {NAMEDOP_RETURN(ICR);}
  327. "--"                 {NAMEDOP_RETURN(DECR);}
  328. "<<"                 {NAMEDOP_RETURN(LS);}
  329. ">>"                 {NAMEDOP_RETURN(RS);}
  330. "<="                 {NAMEDOP_RETURN(LE);}
  331. ">="                 {NAMEDOP_RETURN(GE);}
  332. "=="                 {NAMEDOP_RETURN(EQ);}
  333. "!="                 {NAMEDOP_RETURN(NE);}
  334. "&&"                 {NAMEDOP_RETURN(ANDAND);}
  335. "||"                 {NAMEDOP_RETURN(OROR);}
  336. "*="                 {NAMEDOP_RETURN(MULTassign);}
  337. "/="                 {NAMEDOP_RETURN(DIVassign);}
  338. "%="                 {NAMEDOP_RETURN(MODassign);}
  339. "+="                 {NAMEDOP_RETURN(PLUSassign);}
  340. "-="                 {NAMEDOP_RETURN(MINUSassign);}
  341. "<<="                {NAMEDOP_RETURN(LSassign);}
  342. ">>="                {NAMEDOP_RETURN(RSassign);}
  343. "&="                 {NAMEDOP_RETURN(ANDassign);}
  344. "^="                 {NAMEDOP_RETURN(ERassign);}
  345. "|="                 {NAMEDOP_RETURN(ORassign);}
  346. "..."                {NAMEDOP_RETURN(ELLIPSIS);}
  347.  
  348.  
  349.  
  350. %%
  351.  
  352. /*  I won't bother to provide any error recovery. I won't even handle 
  353. unknown characters */
  354.  
  355. /*******************************************************************/
  356. int isaTYPE(string)
  357. char * string;
  358. {  
  359.  
  360.     /*  We  should  really  be  maintaining  a  symbol  table, and be 
  361.       carefully keeping track of what the current scope is (or in the 
  362.       case of "rescoped" stuff, what scope to  look  in).  Since  the 
  363.       grammar  is  not annotated with actions to track transitions to 
  364.       various scopes, and there is no symbol table, we will supply  a 
  365.       hack  to  allow  folks  to test the grammar out.  THIS IS NOT A 
  366.       COMPLETE IMPLEMENTATION!!!! */
  367.  
  368.     return ('A' <= string[0] && 'Z' >= string[0]);
  369. }
  370.